<!--
 * @description: 通视分析
 * @Author: FengKongLi
 * @Date: 2022-09-26 15:43:47
 * @LastEditors: FengKongLi
 * @LastEditTime: 2022-09-29 14:52:41
-->
<template>
  <div class="container">
    <secen-view @already="already" id="view3D"></secen-view>
    <div class="toolbar">
      <div class="clear" @click="handlerClear">清除</div>
    </div>
  </div>
</template>

<script>
let view3D = null;
export default {
  name: "VisibilityAnalysis",
  data() {
    return {};
  },

  methods: {
    already(viewer) {
      view3D = viewer;
      this.loadModel();
    },
    // 首先把模型加载到地图上
    loadModel() {
      //模型数据加载位置
      // 从以度为单位的经度和纬度值返回 Cartesian3 位置。
      let modelposition = Cesium.Cartesian3.fromDegrees(
        -74.01881302800248,
        40.69114333714821,
        753
      );
      // toRadians将度数转换为弧度。
      let heading = Cesium.Math.toRadians(0.0);
      let pitch = Cesium.Math.toRadians(0.0);
      let roll = Cesium.Math.toRadians(0.0716951918898415);
      // HeadingPitchRoll 表示为航向、俯仰和滚动的旋转。航向是围绕负 z 轴的旋转。俯仰是围绕负 y 轴的旋转。滚动是围绕正 x 轴的旋转。
      let hpRoll = new Cesium.HeadingPitchRoll(heading, pitch, roll);
      let converter = Cesium.Transforms.eastNorthUpToFixedFrame;
      let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
        modelposition,
        hpRoll,
        Cesium.Ellipsoid.WGS84,
        converter
      );
      let tsdyt_model = view3D.scene.primitives.add(
        new Cesium.Cesium3DTileset({
          url: "http://earthsdk.com/v/last/Apps/assets/dayanta/tileset.json",
        })
      );
      tsdyt_model.readyPromise.then(function (tsdyt_model) {
        //请求模型后执行
        tsdyt_model._root.transform = modelMatrix; //模型位置
      });
      view3D.zoomTo(tsdyt_model);
      this.createSecne();
    },
    // 创建一个场景监听事件并添加点实体
    createSecne() {
      let handler = new Cesium.ScreenSpaceEventHandler(view3D.scene.canvas);
      let positions = [];
      let markers = []; //点实体
      handler.setInputAction((movement) => {
        // 拾取位置坐标
        let cartesian = view3D.scene.pickPosition(movement.position);
        if (cartesian) {
          debugger;
          positions.push(cartesian); //加点
          if (markers.length == 0) {
            //创建点实体  开始的点
            let startpoint = view3D.entities.add({
              position: cartesian,
              point: {
                pixelSize: 50,
                color: Cesium.Color.AQUA,
              },
            });
            markers.push(startpoint);
          } else if (markers.length > 0) {
            debugger;
            // 结束的点
            let endpoint = view3D.entities.add({
              position: cartesian,
              point: {
                pixelSize: 50,
                color: Cesium.Color.AQUA,
              },
            });
            markers.push(endpoint);
            handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除左键事件
            this.analysisVisible(positions); //开始分析
          }
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    // * 进行通视分析
    analysisVisible(positions) {
      debugger;
      // 计算射线的方向  normalize标准化
      let direction = Cesium.Cartesian3.normalize(
        //  subtract 计算两个笛卡尔函数的分量差。
        Cesium.Cartesian3.subtract(
          positions[1],
          positions[0],
          new Cesium.Cartesian3()
        ),
        new Cesium.Cartesian3()
      );
      // 建立射线 表示从提供的原点向提供的方向无限延伸的射线。
      // 光线的原点，光线的方向
      let ray = new Cesium.Ray(positions[0], direction);
      // 计算交互点，返回第一个  pickFromRay没找到
      let result = view3D.scene.pickFromRay(ray);
      // console.log(result)
      if (Cesium.defined(result) && Cesium.defined(result.object)) {
        this.drawLine(result.position, positions[0], Cesium.Color.GREEN); // 可视区域
        this.drawLine(result.position, positions[1], Cesium.Color.RED); // 不可视区域
      } else {
        this.drawLine(positions[0], positions[1], Cesium.Color.GREEN);
        console.log("不在模型上");
      }
    },
    // * 绘制线
    drawLine(leftPoint, secPoint, color) {
      let Lines = view3D.entities.add({
        polyline: {
          positions: [leftPoint, secPoint],
          width: 2,
          material: color,
          depthFailMaterial: color,
        },
      });
    },
    handlerClear() {
      view3D.entities.removeAll();
    },
  },
};
</script>
<style lang="scss" scoped>
.container {
  position: relative;
  .toolbar {
    background: rgba($color: #000000, $alpha: 0.6);
    position: absolute;
    top: 1rem;
    color: white;
    padding: 1rem;
    .clear {
      border: white solid 1px;
      padding: 0.5rem 1rem;
    }
  }
}
</style>
